// ==================== Canvas 领域服务 ====================
// 职责：处理Canvas相关的业务逻辑
// 遵循领域驱动设计原则，封装Canvas的核心业务规则

import { ref, computed } from 'vue'
import { 
  useViewportStore, 
  useLayerStore, 
  useSelectionStore, 
  useProjectStore,
  useToolStore
} from '@/stores'

export function useCanvas() {
  // ==================== 依赖注入 ====================
  const viewportStore = useViewportStore()
  const layerStore = useLayerStore()
  const selectionStore = useSelectionStore()
  const projectStore = useProjectStore()
  const toolStore = useToolStore()

  // 暴露stores以便其他服务访问
  const stores = {
    viewportStore,
    layerStore,
    selectionStore,
    projectStore,
    toolStore
  }

  // ==================== 内部状态 ====================
  const canvasRef = ref(null)
  const ctx = ref(null)
  const isInitialized = ref(false)

  // ==================== 计算属性 ====================
  const viewport = computed(() => viewportStore.viewport) // 视口
  const layers = computed(() => layerStore.layers) // 图层
  const selectedObjects = computed(() => selectionStore.selectedObjects) // 选中对象
  const hoveredObject = computed(() => selectionStore.hoveredObject) // 悬停对象
  const isSelecting = computed(() => selectionStore.isSelecting) // 是否选中
  const selectionBox = computed(() => selectionStore.selectionBox) // 选择框
  const currentTool = computed(() => toolStore.currentTool) // 当前工具
  const canvasSettings = computed(() => projectStore.settings) // 画布设置

  // ==================== 坐标转换服务 ====================
  /**
   * 屏幕坐标转世界坐标
   * @param {number} screenX - 屏幕X坐标
   * @param {number} screenY - 屏幕Y坐标
   * @returns {Object} 世界坐标 {x, y}
   */
  const screenToWorld = viewportStore.screenToWorld

  /**
   * 世界坐标转屏幕坐标
   * @param {number} worldX - 世界X坐标
   * @param {number} worldY - 世界Y坐标
   * @returns {Object} 屏幕坐标 {x, y}
   */
  const worldToScreen = (worldX, worldY) => {
    const x = worldX * viewport.value.zoom + viewport.value.x
    const y = worldY * viewport.value.zoom + viewport.value.y
    return { x, y }
  }

  // ==================== 碰撞检测服务 ====================
  /**
   * 获取指定点的对象
   * 按zIndex倒序检测，最上层优先
   * @param {number} x - 世界坐标X
   * @param {number} y - 世界坐标Y
   * @returns {Object|null} 碰撞的对象或null
   */
  const getObjectAtPoint = (x, y) => {
    // 获取所有可见对象
    const allObjects = []
    layers.value.forEach(layer => {
      if (layer.visible) {
        layer.objects.forEach(obj => {
          allObjects.push(obj)
        })
      }
    })
    
    // 按zIndex倒序排序（最上层优先）
    allObjects.sort((a, b) => {
      if (a.zIndex !== b.zIndex) {
        return b.zIndex - a.zIndex
      }
      const layerA = layers.value.find(l => l.id === a.layerId)
      const layerB = layers.value.find(l => l.id === b.layerId)
      return (layerB?.order || 0) - (layerA?.order || 0)
    })

    // 检测碰撞（跳过底图）
    for (const obj of allObjects) {
      // 跳过底图，底图不可选中
      if (obj.isBackground) {
        continue
      }
      
      if (x >= obj.x && x <= obj.x + obj.width &&
          y >= obj.y && y <= obj.y + obj.height) {
        return obj
      }
    }
    
    return null
  }

  /**
   * 检测控制点碰撞
   * @param {number} x - 世界坐标X
   * @param {number} y - 世界坐标Y
   * @param {Object} object - 对象
   * @returns {string|null} 控制点类型或null
   */
  const getControlPointAtPoint = (x, y, object) => {
    if (!object) return null
    
    // 将世界坐标转换为对象局部坐标
    const localX = x - (object.x + object.width / 2)
    const localY = y - (object.y + object.height / 2)
    
    // 考虑对象旋转
    const cos = Math.cos(-object.rotation * Math.PI / 180)
    const sin = Math.sin(-object.rotation * Math.PI / 180)
    const rotatedX = localX * cos - localY * sin
    const rotatedY = localX * sin + localY * cos
    
    const tolerance = 12 // 控制点检测容差（增大容差，更容易点击）
    
    
    
    // 角点控制点检测
    const cornerPoints = [
      { x: -object.width / 2, y: -object.height / 2, type: 'nw' },
      { x: object.width / 2, y: -object.height / 2, type: 'ne' },
      { x: object.width / 2, y: object.height / 2, type: 'se' },
      { x: -object.width / 2, y: object.height / 2, type: 'sw' }
    ]
    
    for (const point of cornerPoints) {
      if (Math.abs(rotatedX - point.x) <= tolerance && 
          Math.abs(rotatedY - point.y) <= tolerance) {
        console.log('检测到角点控制点:', point.type, { rotatedX, rotatedY, pointX: point.x, pointY: point.y })
        return point.type
      }
    }
    
    // 边中点控制点检测
    const edgePoints = [
      { x: 0, y: -object.height / 2, type: 'n' },
      { x: object.width / 2, y: 0, type: 'e' },
      { x: 0, y: object.height / 2, type: 's' },
      { x: -object.width / 2, y: 0, type: 'w' }
    ]
    
    for (const point of edgePoints) {
      if (Math.abs(rotatedX - point.x) <= tolerance && 
          Math.abs(rotatedY - point.y) <= tolerance) {
        console.log('检测到边中点控制点:', point.type, { rotatedX, rotatedY, pointX: point.x, pointY: point.y })
        return point.type
      }
    }
    
    // 旋转控制点检测
    const rotationPoint = {
      x: 0,
      y: -object.height / 2 - 20, // 距离对象顶部20像素
      type: 'rotation'
    }
    
    if (Math.abs(rotatedX - rotationPoint.x) <= tolerance && 
        Math.abs(rotatedY - rotationPoint.y) <= tolerance) {
      console.log('检测到旋转控制点:', rotationPoint.type, { rotatedX, rotatedY, pointX: rotationPoint.x, pointY: rotationPoint.y })
      return rotationPoint.type
    }
    
    return null
  }

  /**
   * 计算对象缩放
   * @param {Object} object - 对象
   * @param {string} controlPoint - 控制点类型
   * @param {number} deltaX - X方向变化量
   * @param {number} deltaY - Y方向变化量
   * @returns {Object} 新的对象属性
   */
  const calculateObjectResize = (object, controlPoint, deltaX, deltaY) => {
    const newObject = { ...object }
    
    // 将世界坐标变化量转换为对象局部坐标
    const cos = Math.cos(-object.rotation * Math.PI / 180)
    const sin = Math.sin(-object.rotation * Math.PI / 180)
    const localDeltaX = deltaX * cos - deltaY * sin 
    const localDeltaY = deltaX * sin + deltaY * cos
    
    // 计算新的尺寸
    let newWidth = object.width
    let newHeight = object.height
    let newX = object.x
    let newY = object.y
    
    // 根据控制点类型计算新尺寸和位置
    switch (controlPoint) {
      case 'nw': // 左上角 - 保持右下角不动
        newWidth = Math.max(10, object.width - localDeltaX)
        newHeight = Math.max(10, object.height - localDeltaY)
        // 计算新的左上角位置（保持右下角不变）
        const rightBottomX = object.x + object.width
        const rightBottomY = object.y + object.height
        newX = rightBottomX - newWidth
        newY = rightBottomY - newHeight
        break
        
      case 'ne': // 右上角 - 保持左下角不动
        newWidth = Math.max(10, object.width + localDeltaX)
        newHeight = Math.max(10, object.height - localDeltaY)
        // 计算新的左上角位置（保持左下角不变）
        const leftBottomX = object.x
        const leftBottomY = object.y + object.height
        newX = leftBottomX
        newY = leftBottomY - newHeight
        break
        
      case 'se': // 右下角 - 保持左上角不动
        newWidth = Math.max(10, object.width + localDeltaX)
        newHeight = Math.max(10, object.height + localDeltaY)
        // 左上角位置不变
        newX = object.x
        newY = object.y
        break
        
      case 'sw': // 左下角 - 保持右上角不动
        newWidth = Math.max(10, object.width - localDeltaX)
        newHeight = Math.max(10, object.height + localDeltaY)
        // 计算新的左上角位置（保持右上角不变）
        const rightTopX = object.x + object.width
        const rightTopY = object.y
        newX = rightTopX - newWidth
        newY = rightTopY
        break
        
      case 'n': // 上边 - 保持下边不动
        newHeight = Math.max(10, object.height - localDeltaY)
        // 计算新的左上角位置（保持下边不变）
        const bottomY = object.y + object.height
        newX = object.x
        newY = bottomY - newHeight
        break
        
      case 's': // 下边 - 保持上边不动
        newHeight = Math.max(10, object.height + localDeltaY)
        // 左上角位置不变
        newX = object.x
        newY = object.y
        break
        
      case 'e': // 右边 - 保持左边不动
        newWidth = Math.max(10, object.width + localDeltaX)
        // 左上角位置不变
        newX = object.x
        newY = object.y
        break
        
      case 'w': // 左边 - 保持右边不动
        newWidth = Math.max(10, object.width - localDeltaX)
        // 计算新的左上角位置（保持右边不变）
        const rightX = object.x + object.width
        newX = rightX - newWidth
        newY = object.y
        break
    }
    
    // 更新对象属性
    newObject.width = newWidth
    newObject.height = newHeight
    newObject.x = newX
    newObject.y = newY
    
    return newObject
  }
  

  /**
   * 计算对象旋转
   * @param {Object} object - 对象
   * @param {number} mouseX - 鼠标世界坐标X
   * @param {number} mouseY - 鼠标世界坐标Y
   * @returns {number} 新的旋转角度（度）
   */
  const calculateObjectRotation = (object, mouseX, mouseY) => {
    // 计算对象中心点
    const centerX = object.x + object.width / 2
    const centerY = object.y + object.height / 2
    
    // 计算鼠标相对于对象中心的角度
    const deltaX = mouseX - centerX
    const deltaY = mouseY - centerY
    
    // 计算角度（弧度转度）
    let angle = Math.atan2(deltaY, deltaX) * (180 / Math.PI)
    
    
    // 调整角度，使0度指向右侧
    angle = angle + 90
    
    // 标准化角度到0-360度
    if (angle < 0) {
      angle += 360
    }
    
    return angle
  }

  /**
   * 
   * @param {Object} object - 对象
   * @param {Object} dragStart - 拖拽开始位置
   * @param {number} mouseX - 鼠标世界坐标X
   * @param {number} mouseY - 鼠标世界坐标Y
   * @param {number} startAngle - 开始旋转角度
   * @returns {number} 新的旋转角度（度）
   */
  const calculateObjectRotation2 = (object, dragStart, mouseX, mouseY, startAngle = 0) => {
    // 计算对象中心点
    const centerX = object.x + object.width / 2
    const centerY = object.y + object.height / 2

    // 计算初始化的时候的鼠标向量
    const initialVector = {
      x: dragStart.x - centerX,
      y: dragStart.y - centerY
    }

    // 计算移动后的鼠标向量
    const currentVector = {
      x: mouseX - centerX,
      y: mouseY - centerY
    }

    // 计算初始化向量的弧度
    const initialAngle = Math.atan2(initialVector.y, initialVector.x)

    // 计算移动后的向量的弧度
    const currentAngle = Math.atan2(currentVector.y, currentVector.x)

    // 计算角度差
    const deltaAngle = (currentAngle - initialAngle) * (180 / Math.PI) // 弧度转度
    
    // 将角度差累加到起始角度上（而不是当前角度）
    let newAngle = startAngle + deltaAngle
    
    // 标准化角度到0-360度
    if (newAngle < 0) {
      newAngle += 360
    } else if (newAngle >= 360) {
      newAngle -= 360
    }
    
    
    
    return newAngle
  }

  // ==================== 交互处理服务 ====================
  /**
   * 处理对象选择
   * @param {Object} object - 要选择的对象
   * @param {boolean} addToSelection - 是否添加到多选
   */
  const handleObjectSelection = (object, addToSelection = false) => {
    if (addToSelection) {
      selectionStore.toggleSelection(object)
    } else {
      selectionStore.selectObject(object)
    }
  }

  /**
   * 处理视图平移
   * @param {number} deltaX - X方向偏移
   * @param {number} deltaY - Y方向偏移
   */
  const handleViewPan = (deltaX, deltaY) => {
    viewportStore.panViewport(deltaX, deltaY)
  }

  /**
   * 处理视图缩放
   * @param {number} zoom - 缩放比例
   * @param {number} centerX - 缩放中心X
   * @param {number} centerY - 缩放中心Y
   */
  const handleViewZoom = (zoom, centerX, centerY) => {
    viewportStore.zoomViewport(zoom, centerX, centerY)
  }

  /**
   * 处理对象移动
   * @param {Array} objects - 要移动的对象数组
   * @param {number} deltaX - X方向偏移
   * @param {number} deltaY - Y方向偏移
   */
  const handleObjectMove = (objects, deltaX, deltaY) => {
    objects.forEach(obj => {
      obj.x += deltaX
      obj.y += deltaY
    })
  }

  // ==================== Canvas 初始化服务 ====================
  /**
   * 初始化Canvas
   * @param {HTMLCanvasElement} canvas - Canvas元素
   */
  const initializeCanvas = (canvas) => {
    if (!canvas) return false
    
    canvasRef.value = canvas
    ctx.value = canvas.getContext('2d')
    
    
    // 设置Canvas尺寸（支持高DPI显示器）
    const resizeCanvas = () => {
      const rect = canvas.getBoundingClientRect()
      canvas.width = rect.width * window.devicePixelRatio
      canvas.height = rect.height * window.devicePixelRatio
      ctx.value.scale(window.devicePixelRatio, window.devicePixelRatio)
      
      // 通知应用层更新视口尺寸
      viewportStore.setViewportSize(rect.width, rect.height)
    }
    resizeCanvas()
    
    
    isInitialized.value = true
    return true
  }

  /**
   * 清理Canvas资源
   */
  const cleanupCanvas = () => {
    if (canvasRef.value) {
      // window.removeEventListener('resize', resizeCanvas)
      canvasRef.value = null
      ctx.value = null
      isInitialized.value = false
    }
  }

  // ==================== 渲染服务 ====================
  /**
   * 清空画布
   */
  const clearCanvas = () => {
    if (ctx.value) {
      ctx.value.clearRect(0, 0, ctx.value.canvas.width, ctx.value.canvas.height)
    }
  }

  /**
   * 应用视口变换
   */
  const applyViewportTransform = () => {
    if (ctx.value) {
      ctx.value.save()
      ctx.value.translate(viewport.value.x, viewport.value.y)
      ctx.value.scale(viewport.value.zoom, viewport.value.zoom)
      ctx.value.rotate(viewport.value.rotation)
    }
  }

  /**
   * 恢复视口变换
   */
  const restoreViewportTransform = () => {
    if (ctx.value) {
      ctx.value.restore()
    }
  }

  // ==================== 导出接口 ====================
  return {
    // 状态
    canvasRef, // Canvas元素
    ctx, // 渲染上下文
    isInitialized, // 是否初始化
    
    // 计算属性
    viewport, // 视口
    layers, // 图层
    selectedObjects, // 选中对象
    hoveredObject, // 悬停对象
    isSelecting, // 是否选中
    selectionBox, // 选择框
    currentTool, // 当前工具
    canvasSettings, // 画布设置
    
    // Stores
    stores, // 存储
    viewportStore,
    layerStore,
    selectionStore,
    projectStore,
    toolStore,
    
    // 坐标转换
    screenToWorld,
    worldToScreen,
    
    // 碰撞检测
    getObjectAtPoint,
    getControlPointAtPoint,
    
    // 缩放处理
    calculateObjectResize,
    
    // 旋转处理
    calculateObjectRotation,
    calculateObjectRotation2,

    // 交互处理
    handleObjectSelection,
    handleViewPan,
    handleViewZoom,
    handleObjectMove,
    
    // Canvas管理
    initializeCanvas,
    cleanupCanvas,
    
    // 渲染服务
    clearCanvas,
    applyViewportTransform,
    restoreViewportTransform
  }
}
